package com.gper.edu.vip.behavior.template.jdbc.framework;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class JdbcTemplate {
    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource){
        this.dataSource = dataSource;
    }

    public final List<?> executeQuery(String sql ,RowMapper<?> rowMapper,Object[] values) throws SQLException {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            //1. 获取连接
            conn = getConnection();
            //2. 创建语句集
            stmt = this.createPrepareStatement(conn,sql);
            //3. 执行语句集
            rs = this.executeQuery(stmt,values);
            //4. 处理结果集
            List<?> result = this.parseResultSet(rs,rowMapper);
            return result;
        }catch (Exception e){
            throw e;
        }finally {
            //5. 关闭结果集
            JDBCUtils.close(rs);
            //6. 关闭语句集
            JDBCUtils.close(stmt);
            //7. 关闭连接
            JDBCUtils.close(conn);
        }
    }

    protected List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws SQLException {
        List<Object> result = new ArrayList<>();
        int rowNum = 0;
        while (rs.next()){
            result.add(rowMapper.mapRow(rs,rowNum++));
        }
        return result;
    }

    protected ResultSet executeQuery(PreparedStatement stmt, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++) {
            stmt.setObject(i+1,values[i]);
        }
        return stmt.executeQuery();
    }

    protected PreparedStatement createPrepareStatement(Connection conn, String sql) throws SQLException {
        return conn.prepareStatement(sql);
    }

    protected Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }
}
